#include "Snaker.h"
#include <QThread>

Snaker::Snaker(QObject *parent) : QObject(parent)
{
    mList.clear();
    mPosQueue.clear();

    connect(&mTimer, SIGNAL(timeout()), this, SLOT(timeout()));

    mPosNow = UP;
    isQuickMove = false;
    mColor = QColor(Qt::black);
    mScore = 0;
}

void Snaker::setSnaker(const QList<QPoint> &list)
{
    mList = list;
}

void Snaker::setInterval(int msec)
{
    mTimer.setInterval(msec);
}

int Snaker::interval()
{
    return mTimer.interval();
}

void Snaker::start(int msec)
{
    if(msec)
        mTimer.start(msec);
    else
        mTimer.start();
}

void Snaker::stop()
{
    mTimer.stop();
}

QList<QPoint>& Snaker::getList()
{
    return mList;
}

void Snaker::addPos(Position pos)
{
    mPosQueue.enqueue(pos);
}

void Snaker::clearPos()
{
    mPosQueue.clear();
}

void Snaker::headMove()
{
    QPoint head = mList[0];
    Position p = position(head, mList[1]);

    if( !mPosQueue.isEmpty() )
    {
        mPosNow = mPosQueue.dequeue();
    }

    switch(mPosNow)
    {
    case UP:
        if( p != DOWN )
        {
            head.setY(head.y()-MOVESIZE);

            if( p != UP )
            {
                mList.insert(0, mList[0]);
            }
        }
        else
        {
            head.setY(head.y()+MOVESIZE);
        }
        break;
    case DOWN:
        if( p != UP )
        {
            head.setY(head.y()+MOVESIZE);

            if( p != DOWN )
            {
                mList.insert(0, mList[0]);
            }
        }
        else
        {
            head.setY(head.y()-MOVESIZE);
        }
        break;
    case LEFT:
        if( p != RIGHT )
        {
            head.setX(head.x()-MOVESIZE);

            if( p != LEFT )
            {
                mList.insert(0, mList[0]);
            }
        }
        else
        {
            head.setX(head.x()+MOVESIZE);
        }
        break;
    case RIGHT:
        if( p != LEFT )
        {
            head.setX(head.x()+MOVESIZE);

            if( p != RIGHT )
            {
                mList.insert(0, mList[0]);
            }
        }
        else
        {
            head.setX(head.x()-MOVESIZE);
        }
        break;
    default:
        break;
    }

    mList[0] = head;
}

void Snaker::tailMove()
{
    Position p = position(mList[mList.count()-2], mList[mList.count()-1]);

    int x1 = mList[mList.count()-1].x();
    int x2 = mList[mList.count()-2].x();
    int y1 = mList[mList.count()-1].y();
    int y2 = mList[mList.count()-2].y();

    switch(p)
    {
    case UP:
        y1 -= MOVESIZE;
        break;
    case DOWN:
        y1 += MOVESIZE;
        break;
    case LEFT:
        x1 -= MOVESIZE;
        break;
    case RIGHT:
        x1 += MOVESIZE;
        break;
    default:
        break;
    }

    if( (x1==x2) && (y1==y2) )
    {
        mList.removeLast();
    }

    mList[mList.count()-1].setX(x1);
    mList[mList.count()-1].setY(y1);
}

Snaker::Position Snaker::position(QPoint head, QPoint tail)
{
    Position p = NUL;
    int x1 = head.x();
    int x2 = tail.x();
    int y1 = head.y();
    int y2 = tail.y();

    if(x1 == x2)
    {
        if(y1 > y2)
        {
            p = DOWN;
        }
        else
        {
            p = UP;
        }
    }
    else
    {
        if(x1 > x2)
        {
            p = RIGHT;
        }
        else
        {
            p = LEFT;
        }
    }

    return p;
}

void Snaker::timeout()
{
    emit timeout(ID);
}

void Snaker::setColor(QColor c)
{
    mColor = c;
}

QColor Snaker::getColor()
{
    return mColor;
}

QList<int>& Snaker::keyList()
{
    return mKeyList;
}

void Snaker::addScore(int score)
{
    mScore += score;
}

void Snaker::minusScore(int score)
{
    if((mScore-score) < 0)
    {
        mScore = 0;
        return;
    }
    mScore -= score;
}

void Snaker::setScore(int score)
{
    mScore = score;
}

int Snaker::getScore()
{
    return mScore;
}
